import CryptoJS from 'crypto-js';


export class CryptoHelper {

  constructor() {
  }
  
  base64To16Bytes(b64) {
    var binary = atob(b64);
    var length = binary.length;
    var bytes = new Uint8Array(16);
    for (var i = 0, j = 2; j < length; i++ , j++) {
      // Ignore the top 2 bytes(0x01, 0x08)
      bytes[i] = binary.charCodeAt(j);
    }
    return bytes;
  }

  //Converts a word array to a Uint8Array.
  convertWordArrayToUint8Array(wordArray) {
    // Shortcuts
    var words = wordArray.words;
    var sigBytes = wordArray.sigBytes;

    // Convert
    var u8 = new Uint8Array(sigBytes);
    for (var i = 0; i < sigBytes; i++) {
      var byte = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
      u8[i] = byte;
    }

    return u8;
  }
  //Converts a word array to a Uint8Array.
  convertUint8ArrayToWordArray(u8arr) {
    // Shortcut
    var len = u8arr.length;

    // Convert
    var words = [];
    for (var i = 0; i < len; i++) {
      words[i >>> 2] |= (u8arr[i] & 0xff) << (24 - (i % 4) * 8);
    }

    return CryptoJS.lib.WordArray.create(words, len);
  }
  hexTo16Bytes(hex) {
    var bytes = new Uint8Array(16);
    for (var i = 0, j = 0; i < hex.length; i += 2, j++) {
      var substr = hex.substring(i, i + 2);
      bytes[j] = parseInt(substr, 16);
    }
    return bytes;
  }

  binaryToString(bytes) {
    var result = '';
    for (var i = 0; i < bytes.length; i++) {
      result += String.fromCharCode(bytes[i]);
    }
    return result;
  }

  binaryToHexString(bytes) {
    var result = '';
    for (var i = 0; i < bytes.length; i++) {
      var hex = (bytes[i] & 0xff).toString(16);
      hex = hex.length === 1 ? '0' + hex : hex;
      result += hex;
    }
    return result.toUpperCase();
  }


  test1() {
    // let key=CryptoJS.enc.Utf8.parse("123");
    //let msg=CryptoJS.enc.Utf8.parse("telink_mesh1");
    let msg = new Uint8Array(16);
    let key = new Uint8Array(16);
    for (let i = 0; i < 16; i++) {
      msg[i] = i;
      key[i] = 15 - i;
    }
    let msg_array = this.convertUint8ArrayToWordArray(msg);
    let key_array = this.convertUint8ArrayToWordArray(key);
    let encrypted = CryptoJS.AES.encrypt(msg_array, key_array, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.NoPadding,
    });
    console.log(this.convertWordArrayToUint8Array(encrypted.ciphertext));

    let decrypted = CryptoJS.AES.decrypt(encrypted, key_array, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.NoPadding,
    });

    console.log(this.convertWordArrayToUint8Array(decrypted));
  }

  test2() {

    var data = JSON.stringify({ abc: 'xyz' });

    var encrypted = CryptoJS.AES.encrypt(data, "my-secret");
    console.log(encrypted.toString());

    var decrypted = CryptoJS.AES.decrypt(encrypted, "my-secret");
    var object = JSON.parse(decrypted.toString(CryptoJS.enc.Utf8));
    console.log(object);
    console.log(object.abc);
  }

  test3() {
    let plain = "06010101000000000000000000000000";
    let key = "20572f52364b3f473050415811632d2b";
    let encryptkeyBytes = this.hexTo16Bytes(key);
    let encryptWordArraykeyBytes = this.convertUint8ArrayToWordArray(encryptkeyBytes);
    let codeBytes = this.hexTo16Bytes(plain);
    let codeWordArrayBytes = this.convertUint8ArrayToWordArray(codeBytes);
    let encrypted = CryptoJS.AES.encrypt(codeWordArrayBytes, encryptWordArraykeyBytes, {
      mode: CryptoJS.mode.ECB,                          // 需要导入CryptoJS的ecb.js
      padding: CryptoJS.pad.NoPadding,              // 需要导入CryptoJS的nopadding.js
    });

    var encryptedHexStr = CryptoJS.enc.Hex.parse(encrypted.ciphertext.toString());
    var encryptedBase64Str = CryptoJS.enc.Base64.stringify(encryptedHexStr);
    var decryptedData = CryptoJS.AES.decrypt(encrypted, encryptWordArraykeyBytes, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.NoPadding
    });
    console.log(this.convertWordArrayToUint8Array(decryptedData));
  }

  test4() {
    //let plain = "06010101000000000000000000000000";
    //let key = "20572f52364b3f473050415811632d2b";
    //let encryptkeyBytes = this.hexTo16Bytes(key); 
    //let codeBytes = this.hexTo16Bytes(plain); 
    let codeBytes = new Uint8Array(16);
    let encryptkeyBytes = new Uint8Array(16);
    for (let i = 0; i < 16; i++) {
      codeBytes[i] = i;
      encryptkeyBytes[i] = 15 - i;
    }
    let encryptWordArraykeyBytes = this.convertUint8ArrayToWordArray(encryptkeyBytes);
    let codeWordArrayBytes = this.convertUint8ArrayToWordArray(codeBytes);
    let encrypted = CryptoJS.AES.encrypt(codeWordArrayBytes, encryptWordArraykeyBytes, {
      mode: CryptoJS.mode.ECB,                          // 需要导入CryptoJS的ecb.js
      padding: CryptoJS.pad.NoPadding,              // 需要导入CryptoJS的nopadding.js
    })

    var encryptedHexStr = CryptoJS.enc.Hex.parse(encrypted.ciphertext.toString());
    var encryptedBase64Str = CryptoJS.enc.Base64.stringify(encryptedHexStr);
    var decryptedData = CryptoJS.AES.decrypt(encrypted, encryptWordArraykeyBytes, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.NoPadding
    });
    console.log(this.convertWordArrayToUint8Array(decryptedData));
  }


}